﻿using System;
using System.Runtime.InteropServices;
namespace Moonlite.ExtensionApi
{
    public sealed class MemoryUtils
    {
        private const ushort COMPRESSION_FORMAT_DEFAULT = 1;
        private const uint FILE_ATTRIBUTE_NORMAL = 0x80;
        private const uint FILE_SHARE_READ = 1;
        private const uint FSCTL_SET_COMPRESSION = 0x9c040;
        private const uint GENERIC_READ = 0x80000000;
        private const uint GENERIC_WRITE = 0x40000000;
        public const string KERNEL_DLL = "kernel32";
        private const uint OPEN_ALWAYS = 4;
        private const int UNIX = 0x80;
        private const int WinCE = 3;
        public static IntPtr AllocateUnmanagedMemory(int size)
        {
            if (Environment.OSVersion.Platform == ((PlatformID)0x80))
            {
                return malloc((uint)size);
            }
            return HeapAlloc(GetProcessHeap(), 0, (uint)size);
        }
        [DllImport("kernel32")]
        public static extern bool CloseHandle(IntPtr h);
        public static void CompressFile(string filename)
        {
            uint num3;
            switch (((int)Environment.OSVersion.Platform))
            {
                case 3:
                case 0x80:
                    return;
            }
            IntPtr hDevice = CreateFile(filename, 0xc0000000, 1, IntPtr.Zero, 4, 0x80, IntPtr.Zero);
            if (hDevice == IntPtr.Zero)
            {
                throw new Exception("Can't open file " + filename + ". hDevice is IntPtr.Zero.");
            }
            ushort lpInBuffer = 1;
            DeviceIoControl(hDevice, 0x9c040, ref lpInBuffer, 2, IntPtr.Zero, 0, out num3, IntPtr.Zero);
            CloseHandle(hDevice);
        }
        [DllImport("kernel32")]
        public static extern IntPtr CreateFile(string lpFileName, uint dwDesiredAccess, uint dwShareMode, IntPtr lpSecurityAttributes, uint dwCreationDispostion, uint dwFlagsAndAttributes, IntPtr hTemplateFile);
        [DllImport("kernel32")]
        public static extern bool DeviceIoControl(IntPtr hDevice, uint dwIoControlCode, ref ushort lpInBuffer, uint nInBufferSize, IntPtr lpOutBuffer, uint nOutBufferSize, out uint lpBytesReturned, IntPtr lpOverlapped);
        [DllImport("libc")]
        public static extern void free(IntPtr lpMem);
        public static void FreeUnmanagedMemory(IntPtr ptr)
        {
            if (Environment.OSVersion.Platform == ((PlatformID)0x80))
            {
                free(ptr);
            }
            else
            {
                HeapFree(GetProcessHeap(), 0, ptr);
            }
        }
        [DllImport("kernel32")]
        public static extern IntPtr GetProcessHeap();
        [DllImport("kernel32")]
        public static extern IntPtr HeapAlloc(IntPtr heap, uint flags, uint bytes);
        [DllImport("kernel32")]
        public static extern bool HeapFree(IntPtr heap, uint flags, IntPtr lpMem);
        [DllImport("kernel32")]
        public static extern int lstrlen(IntPtr str);
        [DllImport("libc")]
        public static extern IntPtr malloc(uint bytes);
        [DllImport("libc")]
        public static extern uint strlen(IntPtr lpMem);
        public static int StrLen(IntPtr str)
        {
            if (Environment.OSVersion.Platform == ((PlatformID)0x80))
            {
                return (int)strlen(str);
            }
            return lstrlen(str);
        }
    }
}
